package com.ruoyi.business.dbopt.controller;

import com.alibaba.druid.pool.DruidDataSource;
import com.ruoyi.business.dbopt.service.DbOptService;
import com.ruoyi.business.dbopt.vo.BackDbs;
import com.ruoyi.business.dbopt.vo.OptCommand;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.Arrays;


@Slf4j
@Controller
@RequestMapping("/system/data")
@RequiredArgsConstructor
public class DbController extends BaseController {

    private String prefix = "system/data";

    private final DbOptService service;

    private final BackDbs backDbs;

    private final DruidDataSource dataSource;
    private static String DB_NAME;

    @PostConstruct
    public void initDbName(){
        String url = dataSource.getUrl();
        DB_NAME = url.substring(url.lastIndexOf("/") + 1, url.lastIndexOf("?"));
    }

    @GetMapping("/backup")
    public String backup(ModelMap modelMap)
    {
        modelMap.put("dsName", DB_NAME);
        return prefix + "/backup";
    }

    /**
     * 备份/还原 操作
     * @param optCommand
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/opt")
    @ResponseBody
    public AjaxResult opt(OptCommand optCommand, @RequestPart(value = "file", required = false) MultipartFile file) throws IOException {
        if (optCommand == null || !Arrays.asList(1,2).contains(optCommand.getOpt())){
            return AjaxResult.error("请发送指令");
        }

        log.info("------------------start-----------------");
        optCommand.setDbName( DB_NAME );
        optCommand.setFile(file);
        int opt = optCommand.getOpt();
        if (1 == opt){
            String mailTo = optCommand.getMailTo();
            if (mailTo != null && mailTo.equals("不填")){
                optCommand.setMailTo(null);
            }
            service.backup(optCommand);
        }else if (2 == opt){
            service.restore(optCommand);
        }
        log.info("-------------------end----------------");
        return AjaxResult.success();
    }

    /**
     * 获取已备份的sql文件
     * @param dbName 库名
     * @return
     */
    @PostMapping("/files")
    @ResponseBody
    public TableDataInfo fileList(@RequestParam(required = false, defaultValue = "ry") String dbName) {
        return getDataTable(service.getFileList(dbName));
    }

    /**
     * 删除备份文件
     * @param fileId 文件名
     * @return
     */
    @PostMapping("/del")
    @ResponseBody
    public AjaxResult del(@RequestParam String fileId) {
        service.delFile(fileId);
        return AjaxResult.success();
    }

    /**
     * 获取操作日志
     * @param type  类型：1.备份日志 2.还原日志
     * @return
     */
    @PostMapping("/logs")
    @ResponseBody
    public AjaxResult logs(@RequestParam(defaultValue = "1") Integer type) throws IOException {
        return AjaxResult.success(service.getOptLogList(type, DB_NAME));
    }

    @PostMapping("/backupAll")
    @ResponseBody
    public AjaxResult backupAll(@RequestParam(defaultValue = "pass") String pass) throws IOException {
        if (pass == null || !pass.equals(OptCommand.PASS)){
            return AjaxResult.error();
        }
        this.backup();
        return AjaxResult.success();
    }

    @Scheduled(cron = "${config.cron}")
    public void backup(){
        if (backDbs.getBackDbs().isEmpty()){
            log.info("未配置定时备份表 config.back_dbs");
            return;
        }

        for (String dbName : backDbs.getBackDbs()) {
            try {
                log.info("开始定时备份 {}", dbName);
                OptCommand optCommand = new OptCommand();
                optCommand.setOpt(1);
                optCommand.setFileId(dbName);
                service.backup(optCommand);
                log.info("定时备份结束 {}", dbName);
            }catch (Exception e){
                log.error(String.format("定时备份错误 %s", dbName), e);
            }
        }
    }
}
